package com.example;

public class TraditionalThreadSynchronized {
    public static void main(String[] args) {
        new TraditionalThreadSynchronized().init();

    }

    private void init() {
        // 内部类访问局部变量加final
        // 静态方法中不能new内部类的实例对象，因为内部类要可以访问外部类的成员变量
        // 成员变量属于对象，创建对象后才会给成员变量分配空间，才能访问成员变量
        // main方法是静态方法，静态方法执行的时候可以不用创建对象
        final Outputer outputer = new Outputer();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    outputer.output("zhangxiaoxiang");
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //锁一定要用同一个对象
                    //new Outputer().output("lihuoming");
                    //outputer.output("lihuoming");
                    outputer.output3("lihuoming");
                }
            }
        }).start();
    }

    //加static相当于外部类了，所以可以写静态方法
    static class Outputer {
        String xxx = "";

        public void output(String name) {
            int len = name.length();
            //synchronized (name) {
            //synchronized (xxx) {
            synchronized (this) {
                for (int i = 0; i < len; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println();
            }
        }

        //方法上加synchronized，方法内不能再用synchronized容易死锁
        //用的监视器对象是this对象，用的同一个门栓
        public synchronized void output2(String name) {
            int len = name.length();
            for (int i = 0; i < len; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println();
        }

        //静态方法使用时不用创建类的实例对象，这里的锁用的是Output.class字节码对象，类的字节码在内存中也是一个对象
        //output3和output2不能同步，因为静态方法的锁对象是Outputer.class字节码对象
        public static synchronized void output3(String name) {
            int len = name.length();
            for (int i = 0; i < len; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println();
        }
        public void output4(String name) {
            int len = name.length();
            synchronized (Outputer.class) {
                for (int i = 0; i < len; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println();
            }
        }
    }
}
